package org.outlook.apps.lunar;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class Lunar {

	static SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
	int year;
	int month;
	int day;
	boolean leap;
	int length;
	int yearCyl;
	int monCyl;
	int dayCyl;
	int daysOfMonth = 0;
	int firstWeek;

	/**
	 * 传出y年m月d日对应的农历. yearCyl3:农历年与1864的相差数 ? monCyl4:从1900年1月31日以来,闰月数
	 * dayCyl5:与1900年1月31日相差的天数,再加40 ?
	 * 
	 * @param cal
	 * @return
	 */
	public Lunar(Calendar cal) {
		int leapMonth = 0;
		Date baseDate = null;
		try {
			baseDate = chineseDateFormat.parse("1900年1月31日");
		} catch (ParseException e) {
			e.printStackTrace(); // To change body of catch statement use Options | File Templates.
		}

		// 求出和1900年1月31日相差的天数
		int offset = (int) ((cal.getTime().getTime() - baseDate.getTime()) / 86400000L);
		dayCyl = offset + 40;
		monCyl = 14;

		// 用offset减去每农历年的天数
		// 计算当天是农历第几天
		// i最终结果是农历的年份
		// offset是当年的第几天
		int iYear, daysOfYear = 0;
		for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) {
			daysOfYear = yearDays(iYear);
			offset -= daysOfYear;
			monCyl += 12;
		}
		if (offset < 0) {
			offset += daysOfYear;
			iYear--;
			monCyl -= 12;
		}
		// 农历年份
		year = iYear;
		yearCyl = iYear - 1864;
		leapMonth = LunarUtil.leapMonth(iYear); // 闰哪个月,1-12
		leap = false;

		// 用当年的天数offset,逐个减去每月（农历）的天数，求出当天是本月的第几天
		int iMonth, daysOfMonth = 0;
		for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {
			// 闰月
			if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) {
				--iMonth;
				leap = true;
				daysOfMonth = LunarUtil.leapDays(year);
			} else
				daysOfMonth = LunarUtil.monthDays(year, iMonth);

			offset -= daysOfMonth;
			// 解除闰月
			if (leap && iMonth == (leapMonth + 1))
				leap = false;
			if (!leap)
				monCyl++;
		}
		// offset为0时，并且刚才计算的月份是闰月，要校正
		if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {
			if (leap) {
				leap = false;
			} else {
				leap = true;
				--iMonth;
				--monCyl;
			}
		}
		// offset小于0时，也要校正
		if (offset < 0) {
			offset += daysOfMonth;
			--iMonth;
			--monCyl;
		}
		month = iMonth;
		day = offset + 1;
		
		this.daysOfMonth = daysOfMonth;
		this.firstWeek = cal.get(Calendar.DAY_OF_WEEK);
	}

	// ====== 传回农历 y年的总天数
	final private static int yearDays(int y) {
		int i, sum = 348;
		for (i = 0x8000; i > 0x8; i >>= 1) {
			if ((LunarUtil.lunarInfo[y - 1900] & i) != 0)
				sum += 1;
		}
		return (sum + LunarUtil.leapDays(y));
	}

	public String toString() {
		return year + "年" + (leap ? "闰" : "") + LunarUtil.chineseNumber[month - 1] + "月" + LunarUtil.getChinaDayString(day);
	}

	public static void main(String[] args) throws ParseException {
		Calendar today = Calendar.getInstance();
//		today.setTime(chineseDateFormat.parse("2003年1月1日"));
		Lunar lunar = new Lunar(today);
		System.out.println("时间：" + chineseDateFormat.format(today.getTime()) + "　农历" + lunar);

		LunarElement[] elements = LunarUtil.calendar(today.get(Calendar.YEAR), today.get(Calendar.MONTH));
		for(LunarElement el : elements)
			System.out.println(el);
	}
}
